<template>
    <el-dropdown>
        <el-button type="primary">
            <label for="file_for_one">
                <el-icon class="el-icon--right">
                    <Upload/>
                </el-icon>
                <span style="margin-left: 4px;">上传</span>
            </label>
        </el-button>
        <template #dropdown>
            <el-dropdown-menu class="file-upload-dropdown">
                <el-dropdown-item>
                    <label class="file-input-trigger" for="file_for_one">上传文件</label>
                </el-dropdown-item>
                <el-dropdown-item>
                    <label class="file-input-trigger" for="file_for_directory">上传文件夹</label>
                </el-dropdown-item>
            </el-dropdown-menu>
        </template>
    </el-dropdown>
    <!-- 实现选择文件上传 -->
    <input type="file" multiple ref="fileOne" @change="selectFileChange" id="file_for_one"
           style="overflow: hidden;position: fixed;width: 1px;height: 1px;z-index: -1;opacity: 0;">
    <!-- 实现选择文件夹上传 -->
    <input type="file" multiple ref="fileDirectory" @change="selectDirectoryChange" id="file_for_directory"
           allowdirs="true" directory="true" webkitdirectory="true"
           style="overflow: hidden;position: fixed;width: 1px;height: 1px;z-index: -1;opacity: 0;">

    <div class="upload-file-list" v-show="showUploadList && fileListData.length > 0">
        <div class="header d-flex">
            <div class="title" style="flex:1">上传列表</div>
            <div class="close-btn" @click="showUploadList=false">
                <el-icon>
                    <arrow-down-bold/>
                </el-icon>
            </div>
        </div>
        <el-table :data="fileListData" style="width: 100%" empty-text="请选择要上传的文件">
            <el-table-column prop="name" label="名称"/>
            <el-table-column label="进度" width="80">
                <template #default="data">
                    <span>{{ Math.ceil(data.row.progress) }}%</span>
                </template>
            </el-table-column>
            <el-table-column label="状态" width="80">
                <template #default="data">
                    <span v-if="data.row.status == FileStatus.Ready">等待上传</span>
                    <span v-if="data.row.status == FileStatus.Uploading">上传中</span>
                    <span v-if="data.row.status == FileStatus.Processing">处理中</span>
                    <span v-if="data.row.status == FileStatus.Error">上传错误</span>
                    <span v-if="data.row.status == FileStatus.Success">上传完成</span>
                </template>
            </el-table-column>
            <el-table-column width="80">
                <template #default="data">
                    <el-button v-if="data.row.status != FileStatus.Uploading" @click="removeFile(data.row)" size="small"
                               circle type="primary"
                               :icon="CloseBold"/>
                </template>
            </el-table-column>
        </el-table>
    </div>
    <el-icon v-if="fileListData.length > 0" class="transfer-icon" @click="showUploadList = true">
        <svg class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg">
            <path
                d="M266.24 20.48a61.44 61.44 0 0 1 61.15328 55.54176L327.68 81.92v671.1296l52.71552-72.37632a61.44 61.44 0 0 1 102.64576 67.29728l-3.2768 4.95616-163.84 225.28a63.0784 63.0784 0 0 1-4.096 5.12l-1.80224 1.88416c-7.04512 7.20896-15.48288 12.288-24.45312 15.23712l-2.4576 0.73728a60.17024 60.17024 0 0 1-8.31488 1.76128l-4.21888 0.4096L266.24 1003.52c-2.8672 0-5.7344-0.2048-8.56064-0.57344l-4.17792-0.73728-6.5536-1.80224a60.416 60.416 0 0 1-24.49408-15.1552l-3.35872-3.76832-2.53952-3.2768-163.84-225.28a61.44 61.44 0 0 1 95.68256-76.88192l3.6864 4.62848L204.8 753.09056V81.92A61.44 61.44 0 0 1 266.24 20.48z m491.52 0c2.90816 0 5.7344 0.2048 8.56064 0.57344l4.17792 0.73728 6.5536 1.80224c9.0112 2.90816 17.408 7.9872 24.45312 15.1552l3.39968 3.76832 2.53952 3.2768 163.84 225.28a61.44 61.44 0 0 1-95.6416 76.88192l-3.72736-4.62848L819.2 270.90944V942.08a61.44 61.44 0 0 1-122.59328 5.89824L696.32 942.08V270.86848l-52.71552 72.4992a61.44 61.44 0 0 1-80.85504 16.7936l-4.95616-3.2768a61.44 61.44 0 0 1-16.7936-80.85504l3.23584-4.95616 163.84-225.28a63.0784 63.0784 0 0 1 4.13696-5.12l1.80224-1.92512c7.04512-7.168 15.44192-12.24704 24.41216-15.1552l2.4576-0.77824A60.17024 60.17024 0 0 1 757.76 20.48z"
                p-id="2005"></path>
        </svg>
    </el-icon>
</template>

<script>
import FileUpload from "./FileUpload.vue";
import {Upload, CircleCloseFilled, CloseBold, ArrowDownBold} from '@element-plus/icons-vue'
import Hash from 'browser-md5-file';
import api from "../../service/api";
// 创建计算hash的对象
const hash = new Hash();

const FileStatus = {
    Processing: 0,
    Ready: 1,
    Uploading: 2,
    Success: 3,
    Error: 4
};

export default {
    name: "Index",
    emits: {
        /**
         * 文件上传后的触发此事件
         */
        uploadSuccess: null
    },
    props: {
        /**
         * 当前目录
         */
        currentFolder: {
            type: String,
            default: '/'
        }
    },
    components: {FileUpload, Upload, ArrowDownBold},
    data() {
        return {
            FileStatus,
            showUploadList: false,
            CircleCloseFilled, CloseBold,
            file_input_id: 'file-input', // input元素的id
            uploadDirectory: false, // 是否上传文件
            thread: 3, // 上传线程数
            maxSize: 100 * 1024 * 1024, // 最大允许大小
            fileListData: [],
            fileId: 0,
        }
    },
    methods: {
        selectFileChange(e) {
            // 当选择文件完成后
            this.add(this.$refs.fileOne.files)
        },
        selectDirectoryChange(e) {
            // 当选择文件夹完成后
            this.add(this.$refs.fileDirectory.files)
        },
        removeFile(file) {
            const index = this.fileListData.indexOf(file);// 获取到要删除的下表
            this.fileListData.splice(index, 1)
        },
        /**
         *
         * @param {FileList} files
         */
        add(files) {
            this.showUploadList = true;
            Array.from(files).forEach(file => {
                const size = file.size / 1024 // KB
                if (size < 1024) { // 小于 1024KB
                    hash.md5(file, (err, md5) => {
                        this.fastUpload(file, md5);
                    }, p => console.log(p))
                } else {
                    this.pushUploadFile(file, this.currentFolder)
                }
            })
        },
        // 添加文件到列表 用于展示
        pushUploadFile(file, folder, status = FileStatus.Ready, progress = 0) {
            const f = {
                id: this.fileId++,
                file,
                name: file.name,
                status,
                folder, // 随当前文件选择的目录
                progress,
            };
            this.fileListData.push(f);
            this.uploadFile(f);//直接上传
        },
        /**
         *
         * @param {File} file
         * @param hash
         */
        fastUpload(file, hash) {
            const folder = this.currentFolder;
            api.file.fastUpload({
                name: file.name,
                size: file.size,
                type: file.type,
                hash,
                folder
            }).then(ret => {
                if (ret) {
                    this.$emit('upload-success', {
                        result: ret,
                        file: file
                    })
                    // 已经上传成功了
                    this.pushUploadFile(file, folder, FileStatus.Success, 100)
                } else {
                    this.pushUploadFile(file, folder);
                }
            }).catch(e => {
                this.pushUploadFile(file, folder);
            });
        },
        startUpload() {
            this.fileListData.forEach(f => {
                if (f.status == FileStatus.Ready) {
                    // 开始上传文件
                    this.uploadFile(f)
                }
            })
        },
        uploadFile(f) {
            if (f.status == FileStatus.Ready) {
                f.status = FileStatus.Uploading;
                api.file.upload(f.folder, f.file, (p) => {
                    f.progress = p.progress
                }).then(ret => {
                    console.log(ret)
                    f.status = FileStatus.Success; //
                    this.$emit('upload-success', {
                        result: ret.data,
                        file: f
                    })
                }).catch(e => console.log(e));
            }
        }

    }
}
</script>

<style lang="less">
.file-upload-dropdown {
    .el-dropdown-menu__item {
        padding: 0;
    }

    .file-input-trigger {
        display: block;
        flex: 1;
        padding: 5px 16px;
        cursor: pointer;

        &:hover {
            background-color: var(--el-dropdown-menuItem-hover-fill);
            color: var(--el-dropdown-menuItem-hover-color)
        }
    }
}

.upload-file-list {
    position: absolute;
    right: 10px;
    bottom: 10px;
    width: 600px;
    min-height: 200px;
    max-height: 400px;
    overflow: auto;
    border-radius: 5px;
    z-index: 99;
    background: #fff;
    box-shadow: 0 0 5px rgb(0 0 0 / 30%);

    .header {
        line-height: 40px;
        background-color: var(--el-color-info);
        color: #fff;
        padding-left: 10px;
        //border-radius: ;
    }

    .close-btn {
        display: flex;
        align-items: center;
        padding: 0 10px;
        cursor: pointer;

        &:hover {
            background-color: var(--el-color-info-dark-2);
        }
    }
}

.transfer-icon {
    background-color: var(--el-color-primary);
    position: absolute;
    right: 10px;
    bottom: 10px;
    width: 60px;
    height: 60px;
    border-radius: 50%;
    z-index: 98;
    display: flex;
    align-items: center;
    cursor: pointer;

    &:hover {
        background-color: var(--el-color-primary-dark-2);
    }

    .icon {
        width: 30px;
        height: 30px;
        fill: #fff
    }
}
</style>